/*******************************************************************************
* CSCI321 Major Project 2010 - University of Wollongong                        *
********************************************************************************
* Program:		WeaveEdit                                              *
* Authors:		Simon Allen (Student#: 3457527, Unix: sa655)           *
*			Scott Bellis (Student#: 3479110, Unix: sjb900)         *
*			Jason Benger (Student#: 3454137, Unix: jb960)          *
*			Timothy Newmarch (Student#: 3459263 Unix: tgn336)      *
*			Benjamin Richardson (Student# 3467752, Unix: bjr401)   *
* Supervisor:		Daniel F. Saffioti                                     *
* Modified:		28/10/2010                                             *
* Description:		WeaveEdit is a highly portable collaborative text      *
*			editor and word processor, allowing several users to   *
*			read and edit multiple documents at the same time.     *
*			It is available for Mac OS X, Windows and Linux,       *
*			utilising Nokia's Qt development framework.            *
*******************************************************************************/


#include <QTime>
#include "preferences.h"
#include "ui_preferences.h"


Preferences *Preferences::instance = NULL;

// Setup QSettings pair names for settings.
const char *Preferences::SETTING_SAVE_WINDOW_GEOMETRY = "saveWindowGeometry";
const char *Preferences::SETTING_DEFAULT_NAME = "defaultName";
const char *Preferences::SETTING_DEFAULT_TEXT_COLOUR = "defaultTextColour";
const char *Preferences::SETTING_TAB_WIDTH = "tabWidth";
const char *Preferences::SETTING_CHARACTER_MATCHING = "characterMatching";
const char *Preferences::SETTING_AUTO_COMPLETION = "autoCompletion";
const char *Preferences::SETTING_AUTO_COMPLETION_PREFIX_LENGTH = "autoCompletionPrefixLength";
const char *Preferences::SETTING_LONG_LINE_MARKER = "longLineMarket";
const char *Preferences::SETTING_LONG_LINE_MARKER_POSITION = "longLineMarkerPosition";
const char *Preferences::SETTING_DEFAULT_TEXT_FONT = "defaultTextFont";
const char *Preferences::SETTING_DEFAULT_TEXT_FONT_SIZE = "defaultTextFontSize";
const char *Preferences::SETTING_DEFAULT_FORMATTED_FONT = "defaultFormattedFont";
const char *Preferences::SETTING_DEFAULT_FORMATTED_FONT_SIZE = "defaultFormattedFontSize";
const char *Preferences::SETTING_USE_SYSTEM_TEXT_FONT = "useSystemTextFont";
const char *Preferences::SETTING_USE_SYSTEM_FORMATTED_FONT = "useSystemFormattedFont";


Preferences::Preferences(QWidget *parent) : QDialog(parent), ui(new Ui::Preferences)
{
	ui->setupUi(this);

	pushButton_defaultTextColour = new ColourButton(this);
	settings = new QSettings(QString(PROGRAM_NAME).toLower(),
				 QString(PROGRAM_NAME).toLower(), this);

	ui->gridLayout_userSettings->addWidget(pushButton_defaultTextColour, 1, 1);

	connect(this, SIGNAL(accepted()), this, SLOT(writeSettings()));
	connect(this, SIGNAL(rejected()), this, SLOT(readSettings()));
	connect(ui->pushButton_clearSettings, SIGNAL(clicked()), this, SLOT(clearSettings()));

	//connect the check buttons to disable/enable the associated drop down buttons
	connect(ui->checkBox_autoCompletion, SIGNAL(toggled(bool)), ui->spinBox_autoCompletionPrefixLength, SLOT(setEnabled(bool)));
	connect(ui->checkBox_longLineMarker, SIGNAL(toggled(bool)), ui->spinBox_longLineMarkerPosition, SLOT(setEnabled(bool)));
	connect(ui->checkBox_systemTextFont, SIGNAL(toggled(bool)), ui->fontComboBox_defaultTextFont, SLOT(setDisabled(bool)));
	connect(ui->checkBox_systemTextFont, SIGNAL(toggled(bool)), ui->spinBox_defaultTextFontSize, SLOT(setDisabled(bool)));
	connect(ui->checkBox_systemFormattedFont, SIGNAL(toggled(bool)), ui->fontComboBox_defaultFormattedFont, SLOT(setDisabled(bool)));
	connect(ui->checkBox_systemFormattedFont, SIGNAL(toggled(bool)), ui->spinBox_defaultFormattedFontSize, SLOT(setDisabled(bool)));

	readSettings();
	writeSettings(); // Write generated defaults from above call.
}

Preferences::~Preferences()
{
	delete ui;
}

/**
  * Set a given value.
  */
void Preferences::setValue(const QString &name, const QVariant &value)
{
	settings->setValue(name, value);
	readSettings();

	emit changed();
}

/**
  * Get a value from file.
  */
QVariant Preferences::getValue(const QString &name, const QVariant &defaultValue) const
{
	return settings->value(name, defaultValue);
}

/**
  * Ensures the first tab is always shown when show()/setVisible() is called.
  */
void Preferences::setVisible(bool visible)
{
	//set the current visible tab to the first one
	if (visible)
		ui->tabWidget->setCurrentIndex(0);

	QDialog::setVisible(visible);
}

/**
  * Write settings out to file.
  */
void Preferences::writeSettings()
{
	settings->setValue(SETTING_DEFAULT_NAME, ui->lineEdit_defaultName->text());
	settings->setValue(SETTING_DEFAULT_TEXT_COLOUR, pushButton_defaultTextColour->getColour());
	settings->setValue(SETTING_TAB_WIDTH, ui->spinBox_tabWidth->value());
	settings->setValue(SETTING_CHARACTER_MATCHING, ui->checkBox_characterMatching->isChecked());
	settings->setValue(SETTING_AUTO_COMPLETION, ui->checkBox_autoCompletion->isChecked());
	settings->setValue(SETTING_AUTO_COMPLETION_PREFIX_LENGTH, ui->spinBox_autoCompletionPrefixLength->value());
	settings->setValue(SETTING_LONG_LINE_MARKER, ui->checkBox_longLineMarker->isChecked());
	settings->setValue(SETTING_LONG_LINE_MARKER_POSITION, ui->spinBox_longLineMarkerPosition->value());
	settings->setValue(SETTING_DEFAULT_TEXT_FONT, ui->fontComboBox_defaultTextFont->currentFont());
	settings->setValue(SETTING_DEFAULT_TEXT_FONT_SIZE, ui->spinBox_defaultTextFontSize->value());
	settings->setValue(SETTING_DEFAULT_FORMATTED_FONT, ui->fontComboBox_defaultFormattedFont->currentFont());
	settings->setValue(SETTING_DEFAULT_FORMATTED_FONT_SIZE, ui->spinBox_defaultFormattedFontSize->value());
	settings->setValue(SETTING_USE_SYSTEM_TEXT_FONT, ui->checkBox_systemTextFont->isChecked());
	settings->setValue(SETTING_USE_SYSTEM_FORMATTED_FONT, ui->checkBox_systemFormattedFont->isChecked());

	emit changed();
}

/**
  * Reads preferences from the settings file. If a preference is not set, the default is set instead
  */
void Preferences::readSettings()
{
	//if settings have not been set yet, set defaults
	if (settings->allKeys().isEmpty())
	{
		QString username;

		#ifdef _WIN32
			username = getenv("USERNAME");
		#else
			username = getenv("USER");
		#endif

		settings->setValue(SETTING_DEFAULT_NAME, username);

		//choose a nice default colour if one is not set
		pushButton_defaultTextColour->setToRandomColour();
		settings->setValue(SETTING_DEFAULT_TEXT_COLOUR, pushButton_defaultTextColour->getColour());

		//set the options for text editor (the default values are specified in constants.h)
		settings->setValue(SETTING_TAB_WIDTH, DEFAULT_TAB_WIDTH);
		settings->setValue(SETTING_CHARACTER_MATCHING, DEFAULT_CHAR_MATCHING_ENABLED);
		settings->setValue(SETTING_AUTO_COMPLETION, DEFAULT_AUTO_COMPLETE_ENABLED);
		settings->setValue(SETTING_AUTO_COMPLETION_PREFIX_LENGTH, DEFAULT_WORD_COMPLETION_LENGTH);
		settings->setValue(SETTING_LONG_LINE_MARKER, DEFAULT_RIGHT_MARGIN_ENABLED);
		settings->setValue(SETTING_LONG_LINE_MARKER_POSITION, DEFAULT_RIGHT_MARGIN);

		//set default font settings
		settings->setValue(SETTING_DEFAULT_FORMATTED_FONT_SIZE, DEFAULT_FONT_SIZE);
		settings->setValue(SETTING_DEFAULT_TEXT_FONT_SIZE, DEFAULT_FONT_SIZE);
		settings->setValue(SETTING_DEFAULT_TEXT_FONT, QFont("Monospace"));
		settings->setValue(SETTING_USE_SYSTEM_TEXT_FONT, DEFAULT_USE_SYSTEM_FONTS);
		settings->setValue(SETTING_USE_SYSTEM_FORMATTED_FONT, DEFAULT_USE_SYSTEM_FONTS);
	}

	ui->lineEdit_defaultName->setText(settings->value(SETTING_DEFAULT_NAME).toString());
	pushButton_defaultTextColour->setColour(settings->value(SETTING_DEFAULT_TEXT_COLOUR).value<QColor>());
	ui->spinBox_tabWidth->setValue(settings->value(SETTING_TAB_WIDTH).toInt());
	ui->checkBox_characterMatching->setChecked(settings->value(SETTING_CHARACTER_MATCHING).toBool());
	ui->checkBox_autoCompletion->setChecked(settings->value(SETTING_AUTO_COMPLETION).toBool());
	ui->spinBox_autoCompletionPrefixLength->setValue(settings->value(SETTING_AUTO_COMPLETION_PREFIX_LENGTH).toInt());
	ui->checkBox_longLineMarker->setChecked(settings->value(SETTING_LONG_LINE_MARKER).toBool());
	ui->spinBox_longLineMarkerPosition->setValue(settings->value(SETTING_LONG_LINE_MARKER_POSITION).toInt());
	ui->fontComboBox_defaultTextFont->setCurrentFont(settings->value(SETTING_DEFAULT_TEXT_FONT).value<QFont>());
	ui->spinBox_defaultTextFontSize->setValue(settings->value(SETTING_DEFAULT_TEXT_FONT_SIZE).toInt());
	ui->fontComboBox_defaultFormattedFont->setCurrentFont(settings->value(SETTING_DEFAULT_FORMATTED_FONT).value<QFont>());
	ui->spinBox_defaultFormattedFontSize->setValue(settings->value(SETTING_DEFAULT_FORMATTED_FONT_SIZE).toInt());
	ui->checkBox_systemTextFont->setChecked(settings->value(SETTING_USE_SYSTEM_TEXT_FONT).toBool());
	ui->checkBox_systemFormattedFont->setChecked(settings->value(SETTING_USE_SYSTEM_FORMATTED_FONT).toBool());
	ui->checkBox_systemTextFont->setChecked(settings->value(SETTING_USE_SYSTEM_TEXT_FONT, true).toBool());
	ui->checkBox_systemFormattedFont->setChecked(settings->value(SETTING_USE_SYSTEM_FORMATTED_FONT, true).toBool());
}

/**
  * Read default settings in.
  */
void Preferences::clearSettings()
{
	settings->clear();
	readSettings();
}
